<script lang="ts" setup>
import { reactive, ref, defineOptions, onUnmounted } from 'vue'
import { User, Lock, EditPen, Message } from '@element-plus/icons-vue'
import { FormProps, FormInstance, ElMessage, FormRules } from 'element-plus'
import { useTouristStore } from '@/stores'
import {
  touristLoginService,
  touristRegisterService,
  getCaptchaService,
  getEmailCode,
  touristFindPasswordService,
  findPasswordService,
} from '@/api/login'
import { useRouter } from 'vue-router'
defineOptions({
  name: 'indexLogin',
})
onUnmounted(() => {
  clearInterval(time.value)
  if (timer.value) {
    clearInterval(timer.value)
    timer.value = null
  }
})
const labelPosition = ref<FormProps['labelPosition']>('top')
const isPageConversion = ref(false)
const router = useRouter() //路由创建
const drawCode = ref('') //图形验证码图形
const Code = ref('') //图形验证码
const clickTimes = ref(0) //图形验证码点击次数
const lastClickTime = ref(0) //最后一次点击图形验证码时间戳
const remainingTime = ref(0) //图形验证码冷却时间
const timer = ref(null) //图形验证码定时器
const cooldown = ref(0) //图形验证码计算冷却时间
const totalsecond = ref(60) //邮箱验证码总秒数
const second = ref(60) //邮箱验证码当前秒数
const time = ref(null) //邮箱验证码定时器
const sendemail = ref(false) //注册表单发送邮箱按钮disable
const sendeFindEmail = ref(false) //找回表单发送邮箱按钮disable
const forml = ref(true) //登录表单disable
const formres = ref(false) //注册表单disable
const formret = ref(false) //找回密码表单disable
const findDisabled = ref(true) //找回密码按钮disable
const findEmail = ref(false) //找回密码邮箱disable
//登录表单
const formLogin = ref({
  username: null,
  password: '',
  icon: '',
})
//注册表单
const formregister = ref({
  username: null,
  password: '',
  icon: '',
  note: null,
})
//找回密码表单
const formretrieve = ref({
  username: null,
  icon: '',
  note: null,
  password: '',
  confirm: '',
})
//邮箱校验规则
const emailRules = (rule, value, callback) => {
  if (!value) {
    callback()
    return
  }
  const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
  if (!emailRegex.test(value)) {
    callback(new Error('请输入有效的邮箱地址'))
  } else {
    callback()
  }
}
//图形验证码校验规则
const captchaRules = (rule, value, callback) => {
  if (!value) {
    callback(new Error('请输入图形验证码'))
    return
  }
  if (value !== Code.value) {
    updatecaptchaImage()
    callback(new Error('验证码错误'))
  } else {
    callback()
  }
}
// 登录表单对应Ref验证
const formLoginRef = ref<FormInstance | null>(null)
const Loginrules = reactive<FormRules<null>>({
  username: [
    { required: true, message: '请输入邮箱', trigger: ['change', 'blur'] },
    { required: true, validator: emailRules, trigger: 'blur' },
  ],
  password: [
    { required: true, message: '请输入密码', trigger: ['change', 'blur'] },
    { min: 6, message: '密码长度至少为6位', trigger: 'blur' },
  ],
  icon: [{ required: true, validator: captchaRules, trigger: 'blur' }],
})

//注册表单对应Ref验证
const formregisterRef = ref<FormInstance | null>(null)
const registerrules = reactive<FormRules<null>>({
  username: [
    { required: true, message: '请输入邮箱', trigger: ['change', 'blur'] },
    { required: true, validator: emailRules, trigger: 'blur' },
  ],
  password: [
    { required: true, message: '请输入密码', trigger: ['change', 'blur'] },
    { min: 6, message: '密码长度至少为6位', trigger: 'blur' },
  ],
  icon: [{ required: true, validator: captchaRules, trigger: 'blur' }],
  note: [{ required: true, message: '请输入验证码', trigger: 'change' }],
})
//二次密码校验
const equalToPassword = (rule, value, callback) => {
  if (formretrieve.value.password !== value) {
    callback(new Error('两次输入的密码不一致'))
  } else {
    callback()
  }
}
//找回密码表单对应Ref验证
const formretrieveRef = ref<FormInstance | null>(null)
const retrieverules = reactive<FormRules<null>>({
  username: [
    { required: true, message: '请输入邮箱', trigger: ['change', 'blur'] },
    { required: true, validator: emailRules, trigger: 'blur' },
  ],
  password: [
    { required: true, message: '请输入密码', trigger: ['change', 'blur'] },
    { min: 6, message: '密码长度至少为6位', trigger: 'blur' },
  ],
  icon: [{ required: true, validator: captchaRules, trigger: 'blur' }],
  note: [{ required: true, message: '请输入验证码', trigger: 'change' }],
  confirm: [
    { required: true, message: '请再次输入您的密码', trigger: ['change', 'blur'] },
    { required: true, validator: equalToPassword, trigger: 'blur' },
  ],
})
// 获取图形验证码
const updatecaptchaImage = async () => {
  const now = Date.now()
  if (remainingTime.value > 0) {
    ElMessage.error(`验证码刷新次数过多，请${remainingTime.value}秒后再试`)
    return
  }
  if (now - lastClickTime.value > 30000) {
    clickTimes.value = 0
  }
  clickTimes.value++
  lastClickTime.value = now
  if (clickTimes.value > 4) {
    cooldown.value = now + 30000 //  30s冷却
    if (timer.value) {
      clearInterval(timer.value)
      timer.value = null
    }
    timer.value = setInterval(() => {
      const timeLeft = Math.max(0, Math.ceil((cooldown.value - Date.now()) / 1000))
      remainingTime.value = timeLeft // 手动更新 remainingTime
      if (timeLeft <= 0) {
        clearInterval(timer.value)
        timer.value = null
        clickTimes.value = 0
      }
    }, 1000)
    return
  }
  const rest = await getCaptchaService()
  if (rest.data.code === 200) {
    drawCode.value = rest.data.image
    Code.value = rest.data.icon
  } else {
    ElMessage.error('获取图形验证码失败')
  }
}
updatecaptchaImage()
//获取验证码
const getCode = async (formRefA, email, text) => {
  //单独校验email和图形验证码
  if (formRefA === 'formregister') {
    await formregisterRef.value.validateField(['username', 'password']) //, 'icon'
  } else {
    await formretrieveRef.value.validateField(['username', 'icon'])
  }
  console.log('校验成功')
  sendemail.value = true
  sendeFindEmail.value = true
  //开启倒计时
  time.value = setInterval(() => {
    if (second.value > 0) {
      second.value--
    } else {
      clearInterval(time.value)
      sendemail.value = false
      sendeFindEmail.value = false
      time.value = null //重置定时器
      second.value = totalsecond.value
    }
  }, 1000)
  const rest = await getEmailCode(email, text)
  if (rest.data.code === 200) {
    ElMessage.success(rest.data.msg)
  } else {
    ElMessage.error('获取验证码失败')
  }
}
// 登录提交
const loginTourist = async () => {
  await formLoginRef.value.validate()
  console.log('校验成功')
  console.log(formLogin.value.username.trim())
  const rest = await touristLoginService(formLogin.value.username.trim(), formLogin.value.password)
  if (rest.data.code === 200) {
    ElMessage.success(rest.data.msg)
    const touristStore = useTouristStore()
    touristStore.setToken(rest.data.token)
    touristStore.setId(rest.data.id)
    touristStore.setName(rest.data.name)
    router.replace('/')
  }
}
//注册提交
const registerTourist = async () => {
  await formregisterRef.value.validate()
  console.log('校验成功')
  console.log(formregister.value.username.trim())
  const rest = await touristRegisterService(
    formregister.value.username.trim(),
    formregister.value.password,
    formregister.value.note,
  )
  if (rest.data.code === 200) {
    ElMessage.success(rest.data.msg)
    isformlogin()
  }
}
//找密码的验证按钮-->短信验证码-->请求
const findEmailCode = async () => {
  await formretrieveRef.value.validateField(['username', 'icon', 'note'])
  console.log('校验成功')
  const rest = await touristFindPasswordService(
    formretrieve.value.username.trim(),
    formretrieve.value.note,
  )
  if (rest.data.code === 200) {
    ElMessage.success(rest.data.msg)
    findDisabled.value = false
    findEmail.value = true
    sendeFindEmail.value = true
  }
}
//找回密码提交
const findPassword = async () => {
  await formretrieveRef.value.validateField(['password', 'confirm'])
  console.log('校验成功')
  const rest = await findPasswordService(
    formretrieve.value.username.trim(),
    formretrieve.value.password,
    formretrieve.value.note,
  )
  if (rest.data.code === 200) {
    ElMessage.success(rest.data.msg)
    isformlogin()
  }
  findDisabled.value = true
  findEmail.value = false
  sendeFindEmail.value = false
}
//表单切换
const isformregister = () => {
  forml.value = false
  formres.value = true
  updatecaptchaImage()
}
const isformretrieve = () => {
  forml.value = false
  formret.value = true
  updatecaptchaImage()
}
const isformlogin = () => {
  forml.value = true
  formret.value = false
  formres.value = false
  updatecaptchaImage()
}
const handleAnimationEnd = () => {
  isPageConversion.value = true
}
</script>

<template>
  <div class="container">
    <div class="oneText">一起遨游星际吧<br /><br /><br />欢迎来到</div>
    <span v-for="i in 10" :key="i" @animationend="handleAnimationEnd"></span>
    <div class="mask" :class="{ animate: isPageConversion }">
      <div class="twoText">云&nbsp;南</div>
      <!-- 登录表单 -->
      <el-form
        v-if="forml"
        :model="formLogin"
        size="large"
        :rules="Loginrules"
        :inline="true"
        ref="formLoginRef"
        class="form-container"
        :labelPosition="labelPosition"
      >
        <el-form-item class="inputSize">
          <div class="formTitle">登录</div>
        </el-form-item>
        <el-form-item prop="username" class="inputSize">
          <!-- <div class="bottunText" >手机号</div> -->
          <el-input
            v-model="formLogin.username"
            style="width: 100%"
            placeholder="请输入邮箱号"
            :prefix-icon="User"
          ></el-input>
        </el-form-item>
        <el-form-item prop="password" class="inputSize">
          <!-- <div class="bottunText">密码</div> -->
          <el-input
            v-model="formLogin.password"
            show-password
            style="width: 100%"
            type="password"
            placeholder="请输入密码"
            :prefix-icon="Lock"
          ></el-input>
        </el-form-item>
        <el-form-item prop="icon" class="inputSize">
          <!-- <div class="bottunText">图形验证码</div> -->
          <el-input
            v-model="formLogin.icon"
            style="width: 80%"
            placeholder="请输入图形验证码"
            :prefix-icon="EditPen"
          ></el-input>
          <el-image :src="drawCode" @click="updatecaptchaImage" />
        </el-form-item>
        <el-form-item class="inputSize">
          <el-button type="primary" class="sendlogin" @click="loginTourist()" plain>登录</el-button>
          <el-button type="success" class="sendrest" @click="isformregister" plain>注册</el-button>
          <el-button type="info" @click="isformretrieve" plain>忘记密码</el-button>
        </el-form-item>
      </el-form>
      <!-- 注册表单 -->
      <el-form
        v-if="formres"
        :model="formregister"
        size="large"
        :rules="registerrules"
        :inline="true"
        ref="formregisterRef"
        class="form-register-container"
        :labelPosition="labelPosition"
      >
        <el-form-item class="inputSize">
          <div class="formTitle">注册</div>
        </el-form-item>
        <el-form-item prop="username" class="inputSize">
          <el-input
            v-model="formregister.username"
            style="width: 100%"
            placeholder="请输入邮箱号"
            :prefix-icon="User"
          ></el-input>
        </el-form-item>
        <el-form-item prop="password" class="inputSize">
          <el-input
            v-model="formregister.password"
            show-password
            style="width: 100%"
            type="password"
            placeholder="请输入密码"
            :prefix-icon="Lock"
          ></el-input>
        </el-form-item>
        <el-form-item prop="icon" class="inputSize">
          <el-input
            v-model="formregister.icon"
            style="width: 80%"
            placeholder="请输入图形验证码"
            :prefix-icon="EditPen"
          ></el-input>
          <el-image :src="drawCode" @click="updatecaptchaImage" />
        </el-form-item>
        <el-form-item prop="note" class="inputSize">
          <el-input
            v-model="formregister.note"
            style="width: 64%"
            placeholder="请输入验证码"
            :prefix-icon="Message"
          ></el-input>
          <el-button
            :disabled="sendemail"
            type="primary"
            class="sendemailstyle"
            plain
            @click="getCode('formregister', formregister.username.trim(), '欢迎注册云穹星迹！')"
            >{{ second === totalsecond ? '获取验证码' : '重新发送(' + second + ')' }}</el-button
          >
        </el-form-item>
        <el-form-item class="inputSize">
          <el-button type="info" class="send" @click="isformlogin" plain>返回</el-button>
          <el-button type="success" class="sendrest" @click="registerTourist()" plain
            >注册</el-button
          >
        </el-form-item>
      </el-form>
      <!-- 找回密码表单 -->
      <el-form
        v-if="formret"
        :model="formretrieve"
        size="large"
        :rules="retrieverules"
        :inline="true"
        ref="formretrieveRef"
        class="form-retrieve-container"
        :labelPosition="labelPosition"
      >
        <el-form-item class="inputSize">
          <div class="formTitle">找回密码</div>
        </el-form-item>
        <el-form-item prop="username" class="inputSize">
          <el-input
            :disabled="findEmail"
            v-model="formretrieve.username"
            style="width: 100%"
            placeholder="请输入邮箱号"
            :prefix-icon="User"
          ></el-input>
        </el-form-item>
        <el-form-item prop="icon" class="inputSize">
          <el-input
            :disabled="findEmail"
            v-model="formretrieve.icon"
            style="width: 80%"
            placeholder="请输入图形验证码"
            :prefix-icon="EditPen"
          ></el-input>
          <el-image :src="drawCode" @click="updatecaptchaImage" />
        </el-form-item>
        <el-form-item prop="note" class="inputSize">
          <el-input
            :disabled="findEmail"
            v-model="formretrieve.note"
            style="width: 64%"
            placeholder="请输入验证码"
            :prefix-icon="Message"
          ></el-input>
          <el-button
            :disabled="sendeFindEmail"
            type="primary"
            class="sendemailstyle"
            plain
            @click="getCode('formretrieve', formretrieve.username.trim(), '找回密码')"
            >{{ second === totalsecond ? '获取验证码' : '重新发送(' + second + ')' }}</el-button
          >
        </el-form-item>
        <el-form-item prop="password" class="inputSize">
          <el-input
            :disabled="findDisabled"
            v-model="formretrieve.password"
            show-password
            style="width: 100%"
            type="password"
            placeholder="请输入新的密码"
            :prefix-icon="Lock"
          ></el-input>
        </el-form-item>
        <el-form-item prop="confirm" class="inputSize">
          <el-input
            :disabled="findDisabled"
            v-model="formretrieve.confirm"
            show-password
            style="width: 100%"
            type="password"
            placeholder="请再次输入密码"
            :prefix-icon="Lock"
          ></el-input>
        </el-form-item>
        <el-form-item class="inputSize">
          <el-button type="info" class="send" @click="isformlogin" plain>返回</el-button>
          <el-button
            type="success"
            class="sendrest"
            :disabled="findEmail"
            @click="findEmailCode()"
            plain
            >验证</el-button
          >
          <el-button type="primary" @click="findPassword()" :disabled="findDisabled" plain
            >修改密码</el-button
          >
        </el-form-item>
      </el-form>
    </div>
    <div class="content">
      <img src="/src/assets/login/星空.png" />
    </div>
  </div>
</template>

<style scoped lang="scss">
/* 登录表单样式 */
.form-container {
  /* background: #29c8e4; */
  width: 50%;
  margin-left: 35%;
  margin-top: 15%;
  height: 40%;
  text-align: center;
  .formTitle {
    color: #fff;
    width: 100%;
    margin: 0 auto;
    height: 10%;
    font-size: 40px;
    text-align: center;
  }
  .inputSize {
    width: 40%;
    height: 10%;
    color: #fff;
    margin-left: 7.5%;
    :deep(.el-input__wrapper) {
      background: rgba(0, 0, 0, 0.2); /* 半透明背景，必要！ */
      backdrop-filter: blur(10px); /* 高斯模糊 */
      -webkit-backdrop-filter: blur(10px);
    }
  }
  // 注册按钮样式
  .sendrest {
    margin-left: 12%;
  }
}
/* 注册表单样式 */
.form-register-container {
  /* background: #29c8e4; */
  width: 50%;
  margin-left: 35%;
  margin-top: 15%;
  height: 40%;
  text-align: center;
  .formTitle {
    color: #fff;
    width: 100%;
    margin: 0 auto;
    height: 10%;
    font-size: 40px;
    text-align: center;
  }
  .inputSize {
    width: 40%;
    height: 10%;
    color: #fff;
    margin-left: 7.5%;
    :deep(.el-input__wrapper) {
      background: rgba(0, 0, 0, 0.2); /* 半透明背景，必要！ */
      backdrop-filter: blur(10px); /* 高斯模糊 */
      -webkit-backdrop-filter: blur(10px);
    }
  }
  //验证码按钮样式
  .sendemailstyle {
    width: 36%;
  }
  // 注册按钮样式
  .sendrest {
    margin-left: 17%;
    width: 60%;
  }
}
// 找回密码表单样式
.form-retrieve-container {
  /* background: #29c8e4; */
  width: 50%;
  margin-left: 35%;
  margin-top: 15%;
  height: 40%;
  text-align: center;
  .formTitle {
    color: #fff;
    width: 100%;
    margin: 0 auto;
    height: 10%;
    font-size: 40px;
    text-align: center;
  }
  .inputSize {
    width: 40%;
    height: 10%;
    color: #fff;
    margin-left: 7.5%;
    :deep(.el-input__wrapper) {
      background: rgba(0, 0, 0, 0.2); /* 半透明背景，必要！ */
      backdrop-filter: blur(10px); /* 高斯模糊 */
      -webkit-backdrop-filter: blur(10px);
    }
  }
  //验证码按钮样式
  .sendemailstyle {
    width: 36%;
  }
  // 注册按钮样式
  .sendrest {
    margin-left: 20%;
  }
}

// 登录按钮样式
.sendlogin {
  width: 30%;
}
.el-button {
  background: rgba(0, 0, 0, 0.2); /* 半透明背景，必要！ */
  backdrop-filter: blur(10px); /* 高斯模糊 */
  -webkit-backdrop-filter: blur(10px);
}
.el-image {
  width: 20%;
  height: 100%;
}
.container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;

  span {
    position: absolute;
    top: 50%;
    right: 50%;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background-color: rgb(255, 255, 255);
    box-shadow:
      0 0 20px rgb(255, 255, 255),
      0 0 20px rgb(255, 255, 255),
      0 0 40px rgb(247, 157, 13);
    z-index: 2;
    opacity: 0;
    animation: moveStar 3s linear 5;

    &::before {
      content: '';
      position: absolute;
      background-color: aliceblue;
      top: 50%;
      transform: translateY(-50%);
      background: linear-gradient(90deg, #fff, transparent);
      width: 300px;
      height: 2px;
    }

    &:nth-child(1) {
      top: 0;
      right: 0;
      animation-delay: 0s;
      animation-duration: 1s;
    }

    &:nth-child(2) {
      top: 0;
      right: 80px;
      animation-delay: 0.5s;
      animation-duration: 1s;
    }

    &:nth-child(3) {
      top: 80px;
      right: 0;
      animation-delay: 0.7s;
      animation-duration: 1s;
    }

    &:nth-child(4) {
      top: 250px;
      right: 0;
      animation-delay: 0.8s;
      animation-duration: 1s;
    }

    &:nth-child(5) {
      top: 100px;
      right: 0;
      animation-delay: 1.5s;
      animation-duration: 1s;
    }

    &:nth-child(6) {
      top: 0;
      right: 24%;
      animation: moveMainStar 3s linear forwards;
      animation-delay: 2s;
    }

    &:nth-child(7) {
      top: 0;
      right: 500px;
      animation-delay: 1s;
      animation-duration: 1s;
    }

    &:nth-child(8) {
      top: 200px;
      right: 0;
      animation-delay: 1.2s;
      animation-duration: 1s;
    }

    &:nth-child(9) {
      top: 0;
      right: 600px;
      animation-delay: 0.8s;
      animation-duration: 1s;
    }

    &:nth-child(10) {
      top: 0;
      right: 200px;
      animation-delay: 1.4s;
      animation-duration: 1s;
    }
  }
}

.oneText {
  position: absolute;
  font-family: STXingkai;
  top: 20%;
  left: 10%;
  height: 60%;
  width: 80%;
  z-index: 2;
  opacity: 1;
  font-size: 120px;
  text-align: center;
  background-image: -webkit-linear-gradient(top, rgb(50, 6, 82), #641fb8, rgb(67, 59, 223));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: oneTextFull 6s linear 1;
}

.twoText {
  position: absolute;
  font-family: STXingkai;
  top: 10%;
  left: 15%;
  height: 25%;
  width: 65%;
  color: #fff;
  font-size: 120px;
  text-align: center;
}

.mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: url('/src/assets/login/雪山.png') no-repeat center center / cover;
  transition: clip-path 3s ease-in-out;
  clip-path: circle(0% at 50% 50%);
  z-index: 2;

  &.animate {
    clip-path: circle(150% at 50% 50%);
  }
}

.content {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  img {
    width: 100%;
    height: 100%;
  }
}

// 动画
@keyframes oneTextFull {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

@keyframes moveMainStar {
  0% {
    transform: rotate(315deg) translateX(0);
    width: 5px;
    height: 5px;
  }
  100% {
    transform: rotate(315deg) translateX(-605px);
    width: 20px;
    height: 20px;
    opacity: 1;
  }
}

@keyframes moveStar {
  0% {
    transform: rotate(315deg) translateX(0);
    opacity: 0;
  }
  90% {
    opacity: 1;
  }
  100% {
    transform: rotate(315deg) translateX(-1000px);
    opacity: 0;
  }
}
</style>
